package ar.edu.utn.frgp.banco.service.impl;


import ar.edu.utn.frgp.banco.dao.ClienteDao;
import ar.edu.utn.frgp.banco.dao.CuentaDao;
import ar.edu.utn.frgp.banco.dao.impl.ClienteDaoImpl;
import ar.edu.utn.frgp.banco.domain.Cliente;
import ar.edu.utn.frgp.banco.domain.Cuenta;
import ar.edu.utn.frgp.banco.domain.enums.TipoCuenta;
import ar.edu.utn.frgp.banco.exceptions.DataAccessException;
import ar.edu.utn.frgp.banco.exceptions.PersonalisedException;
import ar.edu.utn.frgp.banco.exceptions.ServiceException;
import ar.edu.utn.frgp.banco.service.OperacionesClienteServ;
import ar.edu.utn.frgp.banco.utils.Constantes;

public class OperacionesClienteServImpl implements OperacionesClienteServ {

	private ClienteDao clienteDao;
	private CuentaDao cuentaDao;

	public OperacionesClienteServImpl() {
		setClienteDao(new ClienteDaoImpl());
		// cuentaDao = new CuentaDaoImpl()
	}

	@Override
	public void crearCliente(Cliente cliente) throws ServiceException, PersonalisedException {
		if (cliente != null) {
			if (!existeCliente(cliente.getDni())) {
				try {
					clienteDao.altaCliente(cliente);
				} catch (DataAccessException e) {
					throw new ServiceException("Error de acceso a BD."
							+ e.getMessage());
				}
			} else {
				throw new PersonalisedException("El cliente ya existe");
			}
		} else {
			throw new ServiceException("El objeto cliente es null");
		}
	}

	/**
	 * Verifica si el cliente existe
	 * @throws PersonalisedException 
	 * */
	private boolean existeCliente(String dni) throws PersonalisedException {
		try {
			Cliente cl = clienteDao.obtenerCliente(dni);

			if (cl != null)
				return true;

			return false;
		} catch (DataAccessException e) {
			return false;
		}
	}

	@Override
	public void crearCuenta(Cliente cliente, Cuenta cuenta)
			throws ServiceException, PersonalisedException {
		
		if (existeCliente(cliente.getDni())) {
			throw new ServiceException(Constantes.EXCEPCION_CLIENTE_EXISTENTE);
		}
		
		if(TipoCuenta.CAJA_AHORROS.equals(cuenta.getTipoCuenta())){
			if (tieneCajaAhorro(cliente)){
				throw new ServiceException(Constantes.EXCEPCION_CLIENTE_CUENTA_CAJA_EXISTENTE);
			}
		
			cliente.setCajaAhorro(cuenta);
			
		} else if (TipoCuenta.CUENTA_CORRIENTE.equals(cuenta.getTipoCuenta())) {
			if (cuentasCorrientes(cliente) >= 5){
				throw new ServiceException(Constantes.EXCEPCION_CLIENTE_CUENTA_CORRIENTE_MAX_SUPERADO);
			}
			
			cliente.getCuentasCorrientes().add(cuenta);
			
		}
		
		//TODO guardar el cliente.
		
		
	}
	
	private int cuentasCorrientes(Cliente cliente){
		return cliente.getCuentasCorrientes() == null ? 0 : cliente.getCuentasCorrientes().size();
	}
	
	private boolean tieneCajaAhorro(Cliente cliente){		
		if (cliente.getCajaAhorro() != null)
				return true;
		return false;
	}
	
	public ClienteDao getClienteDao() {
		return clienteDao;
	}

	public void setClienteDao(ClienteDao clienteDao) {
		this.clienteDao = clienteDao;
	}

	public CuentaDao getCuentaDao() {
		return cuentaDao;
	}

	public void setCuentaDao(CuentaDao cuentaDao) {
		this.cuentaDao = cuentaDao;
	}

}
